//
// Copyright XinLab Inc (blueapple.mobi) 2006-2008
// Proprietary and confidential
// All rights reserved
//
// $Id: XinBaseUtil.java,v 1.5 2012/05/25 08:00:41 sbho Exp $
//
package com.legleg.util;


import com.legleg.conf.Configure;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.util.*;
import java.util.zip.GZIPInputStream;

public class BaseUtil {

    static final boolean gzip = false;//false;

    static boolean doTrace = true;

    static public void trace(String key, String msg) {
        if (doTrace) {
            System.out.println("[" + key + "] " + msg);
        }
    }

    static private int TIMEOUT = 10000;

    /**
     * get the redirect link, return the original url if it is a actual link or null on errors
     */
    static public final String followRedirect(String url) {
        HttpURLConnection ucon = null;
        InputStream in = null;
        try {
            ucon = (HttpURLConnection) ((new URL(url)).openConnection());
            ucon.setInstanceFollowRedirects(false);
            ucon.setReadTimeout(TIMEOUT);
            ucon.setConnectTimeout(TIMEOUT);
            //ucon.setRequestProperty("Cookie", "age_check=1");
            ucon.connect();
            in = ucon.getInputStream();
            int code = ucon.getResponseCode();

            String loc = null;
            if (code == 303 || code == 302 || code == 301) {
                loc = ucon.getHeaderField("Location");
                if (loc.startsWith("/"))
                    loc = "http://" + ucon.getURL().getHost() + loc;
            } else if (code == 200) {
                loc = url;
            }
            in.close();
            in = null;

            return loc;
        } catch (SocketTimeoutException e) {
            System.out.println(url + " timeout");
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
            if (ucon != null) {
                InputStream err = ucon.getErrorStream();
                if (err != null) {
                    try {
                        while (err.read() >= 0)
                            ;
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    } finally {
                        try {
                            err.close();
                        } catch (IOException e1) {
                            e1.printStackTrace();
                        }
                    }
                }
            }
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                in = null;
            }
        }
        return null;

    }

    /*
    *  return both the redirected link and content
    */
    static public final String[] followRedirectGetContent(String url) {
        return followRedirectGetContent(url, null);
    }

    static public final String[] followRedirectGetContent(String url, String[][] headers) {
        HttpURLConnection ucon = null;
        InputStream in = null;
        try {
            ucon = (HttpURLConnection) ((new URL(url)).openConnection());
            ucon.setInstanceFollowRedirects(false);
            ucon.setReadTimeout(TIMEOUT);
            ucon.setConnectTimeout(TIMEOUT);
            if (gzip && Math.random() < 0.3) {
                ucon.setRequestProperty("Accept-Encoding", "gzip");
            }
            if (headers != null) {
                for (int i = 0; i < headers.length; i++) {
                    if (headers[i] != null) {
                        ucon.setRequestProperty(headers[i][0], headers[i][1]);
                        System.out.println("setting" + headers[i][0] + ": " + headers[i][1]);
                    }
                }
            }
            long starttime = System.currentTimeMillis();
            //ucon.setRequestProperty("Cookie", "age_check=1");
            ucon.connect();
            int code = ucon.getResponseCode();
            int length = ucon.getContentLength();

            String loc = null;
            String html = null;


            if (code == 303 || code == 302 || code == 301) {
                loc = ucon.getHeaderField("Location");
                if (loc == null)
                    return null;
                if (loc.startsWith("/"))
                    loc = "http://" + ucon.getURL().getHost() + loc;
                html = getUrlString(loc);
            } else if (code == 200) {
                loc = url;
                in = new BufferedInputStream(ucon.getInputStream());
//                try{
//                    in = new BufferedInputStream(ucon.getInputStream());
//                }catch (IOException e){
//                    in = new BufferedInputStream(ucon.getErrorStream());
//                }
                if (in == null)
                    return null;
                //StringBuffer sb = new StringBuffer();
//                in = new BufferedInputStream(in);
                String contentencoding = ucon.getHeaderField("Content-Encoding");
                if (gzip && "gzip".equals(contentencoding)) {
                    System.out.println("gzipped");
                    in = new GZIPInputStream(in);
                }
                int n;
                byte[] buf2 = new byte[1024];
                ByteArrayOutputStream buf = new ByteArrayOutputStream(5000);
                while ((n = in.read(buf2)) >= 0) {
                    if (buf.size() > 2 * 1024 * 1024) {
                        System.out.println("***error geturl too long " + url);
                        return null;
                    }
                    buf.write(buf2, 0, n);
                }
                html = buf.toString();
            }

            return new String[]{loc, html};
        } catch (SocketTimeoutException e) {
            System.out.println(url + " timeout");
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
            if (ucon != null) {
                InputStream err = ucon.getErrorStream();
                if (err != null) {
                    try {
                        while (err.read() >= 0)
                            ;
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    } finally {
                        try {
                            err.close();
                        } catch (IOException e1) {
                            e1.printStackTrace();
                        }
                    }
                }
            }
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                in = null;
            }
        }
        return null;
    }

    static final public String getUrlString(String urlString) {
        return getUrlString(urlString, "UTF-8", null, gzip);
    }

    static final public String getUrlString(String urlString, String defaultEncoding) {
        return getUrlString(urlString, defaultEncoding, null, gzip);
    }

    static final public String getUrlString(String urlString, String defaultEncoding, String[][] headers) {
        return getUrlString(urlString, defaultEncoding, headers, gzip);
    }

    static final public String getUrlString(String urlString, String defaultEncoding, String[][] headers, boolean gzip) {
        InputStream in = null;
        HttpURLConnection con = null;
        try {
            URL url = new URL(urlString);
            con = (HttpURLConnection) url.openConnection();
            con.setReadTimeout(TIMEOUT);
            con.setConnectTimeout(TIMEOUT);
            if (gzip && Math.random() < 0.3) {
                con.setRequestProperty("Accept-Encoding", "gzip");
            }
            if (headers != null) {
                for (int i = 0; i < headers.length; i++) {
                    if (headers[i] != null) {
                        con.setRequestProperty(headers[i][0], headers[i][1]);
                        //System.out.println("setting "+headers[i][0]+": "+headers[i][1]);
                    }
                }
            }

            long starttime = System.currentTimeMillis();
            con.connect();

            int code = con.getResponseCode();
            int length = con.getContentLength();

//            String encoding = con.getContentEncoding();
            String encoding2 = con.getHeaderField("Content-Type");
            int index;
            if (encoding2 != null) {
                if ((index = encoding2.indexOf("charset=")) > 0) {
                    encoding2 = encoding2.substring(index + "charset=".length()).replace('"', ' ').replace('\'', ' ').trim();
                } else
                    encoding2 = defaultEncoding;//null;
            }
            in = new BufferedInputStream(con.getInputStream());
//            try{
//                in = new BufferedInputStream(con.getInputStream());
//            }catch (IOException e){
//                in = new BufferedInputStream(con.getErrorStream());
//            }
            if (in == null)
                return null;
            String contentencoding = con.getHeaderField("Content-Encoding");
            if (gzip && "gzip".equals(contentencoding)) {
                System.out.println("gzipped");
                in = new GZIPInputStream(in);
            }
            ByteArrayOutputStream urlData = new ByteArrayOutputStream();
            byte[] buf2 = new byte[1024];
            int n;
            while ((n = in.read(buf2)) >= 0) {
                if (urlData.size() > 2 * 1024 * 1024) {
                    System.out.println("***error geturl too long " + urlString);
                    return null;
                }
                urlData.write(buf2, 0, n);
            }

            if (encoding2 != null) {
                try {
                    return urlData.toString(encoding2);
                } catch (UnsupportedEncodingException e) {
                    //e.printStackTrace();
                    System.out.println("UnsupportedEncodingException detected: " + e.getMessage());
                    return urlData.toString();
                }
            } else {
                return urlData.toString();
            }
//            return encoding2!=null?urlData.toString(encoding2):urlData.toString();
        } catch (SocketTimeoutException e) {
            System.out.println(urlString + " timeout");
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
            if (con != null) {
                InputStream err = con.getErrorStream();
                if (err != null) {
                    try {
                        while (err.read() >= 0)
                            ;
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    } finally {
                        try {
                            err.close();
                        } catch (IOException e1) {
                            e1.printStackTrace();
                        }
                    }
                }
            }
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                in = null;
            }
            if (con != null) {
                try {
                    con.getInputStream().close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                con = null;
            }
        }

        return null;
    }

    static final public String unescapeXML(String s) {
        return s.replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&apos;", "'").replaceAll("&quot;", "\"").replaceAll("&amp;", "&");
    }

    static final public int parseDuration(String s) {
        if (s == null || s.length() == 0)
            return 0;
        int rts = 0;
        s = s.trim();
        StringTokenizer st = new StringTokenizer(s, ":");
        while (st.hasMoreTokens()) {
            try {
                rts = rts * 60 + Integer.parseInt(st.nextToken());
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
        }
        return rts;
    }


    /**
     * parse "00:00:58.9"
     */
    public static int parseDurationWithDot(String str) {

        if (str == null || str.length() == 0)
            return 0;

        int rts = 0;
        String top = str;
        int dp = str.indexOf(".");
        if (dp > 0) top = str.substring(0, dp);

        top = top.trim();
        StringTokenizer st = new StringTokenizer(top, ":");
        try {
            while (st.hasMoreTokens()) {
                rts = rts * 60 + Integer.parseInt(st.nextToken());
            }
        } catch (Exception e) {
            return -1;
        }
        return rts;
    }

    /**
     * parse "1,000,000,145"
     */
    public static int getNumberCommaSep(String str) {
        int tor = 0;
        String top = str.trim();
        StringTokenizer st = new StringTokenizer(top, ",");
        try {
            while (st.hasMoreTokens()) {
                tor = tor * 1000 + Integer.parseInt(st.nextToken());
            }
        } catch (Exception e) {
            return 0;
        }
        return tor;
    }

    public static String normalizeUrl(String url) {
        if (url == null)
            return null;
        if (url.contains("metacafe.com")) {
            if (url.contains("/watch/yt-"))
                return null;
            if (url.contains("www1")) {
                url = url.replace("www1.metacafe.com", "www.metacafe.com");
            }
            //normalize url
            //http://www.metacafe.com/watch/401649/paris_hilton/\\\/\\\/s.mcstatic.com\\\/Flash\\\/comp\\\/PostSocial_1.0.4.swf?tab=2  
            //http://www.metacafe.com/watch/116500/sexy_paris/\/\/s.mcstatic.com
            int index = 40;
            index = url.indexOf('/', index);
            if (index > 0 && url.length() > index + 1) {
                String newurl = url.substring(0, index + 1);
                System.out.println("mc: url normalized " + url + " to " + newurl);
                url = newurl;
            }
        } else if (url.contains("dailymotion.com")) {
            int index3 = url.indexOf("/relevance/search/");
            if (index3 > 0) {
                int index4 = url.indexOf('/', index3 + "/relevance/search/".length());
                url = url.substring(0, index3) + url.substring(index4);
//                System.out.println("dailymotion pageurl stripped:"+oldurl+" "+me.pageurl);
            }
        }
        return url;
    }

    public static final String removeTag(String s) {
        if (s == null) return null;

        int index1 = s.indexOf('<');
        if (index1 < 0)
            return s;
        int index2 = s.indexOf('>', index1);
        if (index2 < 0)
            return s;
        return removeTag(new StringBuffer().append(s.substring(0, index1)).append(s.substring(index2 + 1)).toString());
    }

    public static String gbk2utf(String source) {
        try {
            return new String(source.getBytes("GBK"), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return source;
    }

    public static String utf2gbk(String source) {
        try {
            return new String(source.getBytes("utf-8"), "GBK");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return source;
    }

    public static String getAlbumImageDir(String baseDir, long albumId) {
        return FilenameUtils.concat(baseDir, albumId / 10000 + "/" + albumId / 100 + "/" + albumId);
    }

    public static String getAlbumThumb(long albumId) {
        return Configure.ALBUM_IMAGE_PATH + "/" + albumId / 10000 + "/" + albumId / 100 + "/" + albumId + "/1-70x70.jpg";
    }

    public static String[] getAlbumAllPics(long albumId, int number) {
        String[] ret = new String[number];
        for (int i = 0; i < number; i++) {
            ret[i] = Configure.ALBUM_IMAGE_PATH + "/" + albumId / 10000 + "/" + albumId / 100 + "/" + albumId + "/" + (i + 1) + ".jpg";
        }
        return ret;
    }

    private static String reg = "(?i)\\[\\d+P\\]|\\[BOMB.TV\\]|\\[VYJ\\]|\\[image.tv\\]|\\[WPB-net\\]|\\[Young Animal\\]|\\[Sabra.net\\]|\\[NS Eyes\\]|\\[Beautyleg\\]|\\[sabra\\]|\\[DGC\\]|\\[Ligui\\]|\\[FRIDAY\\]|\\[PB写真集\\]|\\[YS-WEB\\]|\\[Ys web\\]|\\[@misty\\]|\\[Idol Line\\]|\\[Weekly Young Magazine\\]|\\[BWH\\]|\\[WPB\\]|\\[RQ-STAR\\]|\\[縛リ芸術\\]";

    public static String replaceBrands(String source) {
        if (source == null) return source;
        return StringUtils.trimToEmpty(source.replaceAll(reg, ""));
    }

    public static void main(String[] args) {
        String reg = "(?i)\\[\\d+P\\]|\\[BOMB.TV\\]|\\[VYJ\\]|\\[image.tv\\]|\\[WPB-net\\]|\\[Young Animal\\]|\\[Sabra.net\\]|\\[NS Eyes\\]|\\[Beautyleg\\]|\\[sabra\\]|\\[DGC\\]|\\[Ligui\\]|\\[FRIDAY\\]|\\[PB写真集\\]|\\[YS-WEB\\]|\\[Ys web\\]|\\[@misty\\]|\\[Idol Line\\]|\\[Weekly Young Magazine\\]|\\[BWH\\]|\\[WPB\\]|\\[RQ-STAR\\]|\\[縛リ芸術\\]";
        System.out.println("[WPB-net] No.151 星名美津紀 – 美少女の制服の中 [40P]".replaceAll(reg, ""));
    }


    public static TreeMap<String, Integer> getSortedMap(HashMap map) {
        ByValueComparator bvc = new ByValueComparator(map);
        TreeMap<String, Integer> sorted_map = new TreeMap<String, Integer>(bvc);
        sorted_map.putAll(map);
        return sorted_map;
    }
    
    public static List<String> getSortedList(HashMap map){
        ByValueComparator bvc = new ByValueComparator(map);
        List<String> keys = new ArrayList<String>(map.keySet());
        Collections.sort(keys, bvc);
        return keys;
    }

    static class ByValueComparator implements Comparator<String> {
        HashMap<String, Integer> base_map;

        public ByValueComparator(HashMap<String, Integer> base_map) {
            this.base_map = base_map;
        }

        public int compare(String arg0, String arg1) {
            if (!base_map.containsKey(arg0) || !base_map.containsKey(arg1)) {
                return 0;
            }

            if (base_map.get(arg0) < base_map.get(arg1)) {
                return 1;
            } else if (base_map.get(arg0) == base_map.get(arg1)) {
                return 0;
            } else {
                return -1;
            }
        }
    }
}
